Package Project3;

Helpers
            digit = ['0'..'9'];
            lf = 10;
			cr = 13;
			tab = 9*;
            sp = ' ' | tab; 
			eol = lf | cr | cr lf sp* | sp*;
			alpha = ['a'..'z']|['A'..'Z'];
			ascii = ([0..255]);
Tokens
			//and = '&&';
			assign = ':=';
			begin = 'BEGIN';
			bool = 'BOOLEAN';
			break = 'BREAK';
			case = 'CASE';
			colon = ':';
			comma = ',';
			default = 'DEFAULT';
			else = 'ELSE';
			end = 'END';
			eq = '==';
			exc = '!';
			false = 'FALSE';
			for = 'FOR';
			geq = '>=';
			get = 'GET()';
			gt = '>';
            if = 'IF';
			intt = 'INT';
			lbracket = '[';
			quote = '"';
			lcurly = '{';
			lparen = '(';
			leq = '<=';
			lt = '<';
			minus = '-';
			neq = '!=';
			number = (('0') | (['1'..'9'](digit)*));
			//or = '||';
			period = '.';
			plus = '+';
			postdec = '--';
			postinc = '++';
			put = 'PUT';
			//question = '?';
			rbracket = ']';
			return = 'RETURN';
			rcurly = '}';
			realt = 'REAL';
			rparen = ')';
			semicolon = ';';
			string = 'STRING';
			switch = 'SWITCH';
			then = 'THEN';
			times = '*';
			true = 'TRUE';
			void = 'VOID';
			while = 'WHILE';
			div = '/';
			//closedparen = '()';
			whitespace = (sp | eol)*;
			id = alpha(alpha|digit|'_')*;
			anychars = '"'[[[0..255]-34]-32]'"';
Ignored Tokens
  whitespace;

Productions
	prog = begin stmtseq end;

	stmtseq = {a}stmt stmtseq | {empty};

	stmt = {c}id idopt |
		{d}if lparen boolean rparen then lcurly stmtseq rcurly optionalelse |
		{e}while lparen boolean rparen lcurly stmtseq rcurly |
		{f}for lparen id assign expr [fa]:semicolon boolean [fb]:semicolon forexpr rparen lcurly stmtseq rcurly |
		{h}put lparen id rparen semicolon |
		{i}return expr semicolon |
		{j}type id lparen vars rparen curlystmtseq |
		{l}switch [la]:lparen expr [lb]:rparen lcurly case [lc]:lparen int [ld]:rparen [le]:colon [lf]:stmtseq optionalbreak cases default [lg]:colon [lh]:stmtseq rcurly;

    idopt = {a}assign anychars semicolon |
			{b}assign assignrule |
            {c}idlist colon type semicolon |
            {d}postinc semicolon |
            {e}postdec semicolon |
			{f}lparen vars rparen semicolon;

    assignrule = {a} expr semicolon |
				 {b}[af]:quote id [as]:quote semicolon |
                 {c}get semicolon;

	idlist = {a}comma id idlist | {empty};
	optionalelse = {a}else lcurly stmtseq rcurly| {empty};
	forexpr = {a}id postinc | {b}id postdec | {c}id assign expr;
	curlystmtseq = {a}lcurly stmtseq rcurly | {b}semicolon;
	optionalbreak = {a}break semicolon | {empty};
	cases = {a}case lparen int rparen colon stmtseq optionalbreak cases | {empty};
	vars = {a} varlist | {empty};
	varlist = {a} varlist comma id colon type | {b} id colon type;
	expr = {a} expr addop term | {b}term;
	term = {a}term multop factor | {b}factor;
	factor = {a}lparen expr rparen | {b}minus factor | {c}int | {d}real | {e}id | {f}id lparen vars rparen;
	boolean = {a}true | {b}false | {c}[ca]:expr cond [cb]:expr;
	cond = {a}eq | {b}neq | {c}get | {d}leq | {e}gt | {f}lt;
	addop = {a}plus | {b}minus;
	multop = {a}times | {b}div;
	type = {a}intt | {b}realt | {c}string | {d}bool | {e}void;
	int = number;
	real = [a]:int period [b]:int;
